package com.acme.bankapp.service;

import com.acme.bankapp.domain.Bank;
import com.acme.bankapp.domain.Client;
import com.acme.bankapp.domain.accounts.Account;
import com.acme.bankapp.domain.accounts.AccountType;
import com.acme.bankapp.domain.accounts.CheckingAccount;
import com.acme.bankapp.domain.accounts.SavingsAccount;
import com.acme.bankapp.exceptions.NegativeAmountException;
import com.acme.bankapp.exceptions.NotEnoughFundsException;

/**
 *
 * Aggregates delegate methods that perform financial operations over bank's clients' accounts.
 * Holds reference to the Bank object.
 *
 */
public class AccountService {
	public static Account createAccountByType(AccountType accountType, double... balanceAndOverdraft) {
		switch (accountType) {
		case CHECKING:
			return new CheckingAccount(balanceAndOverdraft[0], balanceAndOverdraft[1]);
		case SAVINGS:
			return new SavingsAccount(balanceAndOverdraft[0]);
		}
		return null;
	}

	Bank bank;
	
	/**
	 * Constructs Service with specified Bank.
	 * @param bank
	 */
	public AccountService(Bank bank){
		this.bank = bank;
	}

	/**
	 * Adds amount to client's account.
	 * @param client
	 * @param amount
	 * @param accountId TODO
	 */
	public boolean deposit(Client client, double amount, int accountId) throws NegativeAmountException {
		return client.getAccountById(accountId).deposit(amount);
	}	  

	/**
	 * Withdraws amount from client's account if possible.
	 * Throws exception if not.
	 * @param client
	 * @param amount
	 * @param accountId TODO
	 * @return true if possible to withdraw.
	 * @throws NotEnoughFundsException if funds are depleted.
	 * @throws NegativeAmountException if amount is negative.
	 */
	public boolean withdraw(Client client, double amount, int accountId) throws NegativeAmountException, NotEnoughFundsException {
		System.out.println(accountId);
		return client.getAccountById(accountId).withdraw(amount);
	}

	/**
	 * Withdraws amount from client's account if possible. Client specified by name.
	 * Throws exception if not.
	 * @param client
	 * @param amount
	 * @param accountId TODO
	 * @return true if possible to withdraw.
	 * @throws NotEnoughFundsException if funds are depleted.
	 * @throws NegativeAmountException if amount is negative.
	 */
	public boolean withdraw(String clientName, double amount, int accountId) throws NegativeAmountException, NotEnoughFundsException {
		return withdraw(bank.getClientByName(clientName), amount, accountId);
	}
	/**
	 * Adds amount to account specified by client's name.
	 * @param clientName
	 * @param amount
	 * @param accountId TODO
	 */
	public boolean deposit(String clientName, double amount, int accountId)  throws NegativeAmountException  {
		return bank.getClientByName(clientName).getAccountById(accountId).deposit(amount);
	}

}
